package org.wyw.utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 加减乘除表达式计算
 */
public class Calculator {

    public static BigDecimal conversion(String formula){
        // 对输入公式，按符号/数字，用空格分开，以便后面分组
        String[] inputs = formula.split("");
        String format = "";
        for (String item : inputs) {
            if ("(".equals(item) || ")".equals(item) || "+".equals(item)
                    || "-".equals(item) || "*".equals(item) || "/".equals(item)){
                format += " " + item + " ";
            }else {
                format += item;
            }
        }
        List<String> strings = changeInfixExpressionToPostfixExpression(format);
        Stack<String> stack = new Stack<>();
        for (String item : strings) {
            if ("+".equals(item)){
                BigDecimal a = new BigDecimal(stack.pop());
                BigDecimal b = new BigDecimal(stack.pop());
                stack.add(b.add(a).toString());
            }else if ("-".equals(item)){
                BigDecimal a = new BigDecimal(stack.pop());
                BigDecimal b = new BigDecimal(stack.pop());
                stack.add(b.subtract(a).toString());
            }else if ("*".equals(item)){
                BigDecimal a = new BigDecimal(stack.pop());
                BigDecimal b = new BigDecimal(stack.pop());
                stack.add(b.multiply(a).toString());
            }else if ("/".equals(item)){
                BigDecimal a = new BigDecimal(stack.pop());
                BigDecimal b = new BigDecimal(stack.pop());
                stack.add(b.divide(a,1000, BigDecimal.ROUND_HALF_DOWN).toString());
            }else {
                stack.add(item);
            }
        }
        // 避免太长，只能10位
        return new BigDecimal(stack.pop()).setScale(10, BigDecimal.ROUND_HALF_UP);
    }

    private static List<String> changeInfixExpressionToPostfixExpression(String input){
        List<String> resultList = new ArrayList<>();
        Stack<String> tempStack = new Stack<>();
        String[] splitArray = input.split(" ");
        for (String item : splitArray) {
            if ("".equals(item)){
                continue;
            }
            // 如果字符是右括号的话，说明前面一定有过左括号，将栈里第一个左括号之前全部添加到List里
            if (")".equals(item)){
                while (!"(".equals(tempStack.peek())){
                    resultList.add(tempStack.pop());
                }
                // 去除前面的左括号
                tempStack.pop();
            }else if ("(".equals(item)){
                // 如果是左括号，那么直接添加进去
                tempStack.add("(");
            }else if ("+".equals(item) || "-".equals(item)){
                // 如果是加减号，还需要再判断
                if (tempStack.empty() || "(".equals(tempStack.peek())){
                    tempStack.add(item);
                }else if ("+".equals(tempStack.peek()) || "-".equals(tempStack.peek())){
                    // 读临时栈里的顶部数据，如果也是加减就取出来一个到结果列，这个放临时栈，如果是乘除就开始取到右括号为止
                    resultList.add(tempStack.pop());
                    tempStack.add(item);
                }else {
                    while (!tempStack.empty()){
                        if ("(".equals(tempStack.peek())){
                            break;
                        }else {
                            resultList.add(tempStack.pop());
                        }
                    }
                    tempStack.add(item);
                }
            }else if ("*".equals(item) || "/".equals(item)){
                // 如果是乘除
                if (!tempStack.empty()){
                    // 判断临时栈里栈顶是啥，如果是乘除，取一个出来到结果列，添这个进临时栈
                    if ("*".equals(tempStack.peek()) || "/".equals(tempStack.peek())){
                        resultList.add(tempStack.pop());
                    }
                }
                tempStack.add(item);
            }else {
                // 说明是非符号，都添加进去
                resultList.add(item);
            }
        }
        // 遍历完了，把临时stack里的东西都加到结果stack里去
        while (!tempStack.empty()){
            resultList.add(tempStack.pop());
        }
        return resultList;
    }

    public static void main(String[] args) {
//        System.out.println(conversion("(1+2)*3"));

        // 将从Oracle获取的金额（假设是字符串形式）转换为BigDecimal
//        String amountStr = "10.5"; // 模拟从Oracle获取的金额
//        BigDecimal amount = new BigDecimal(amountStr);
//// 进行运算
//        BigDecimal anotherAmount = new BigDecimal("2.5");
//        BigDecimal result = amount.add(anotherAmount);
//        System.out.println(result);
        String str ="0.1111111111111111111111111111111111111112222222222222";
        Double d = Double.valueOf(str);
        BigDecimal anotherAmount = new BigDecimal(str);
        System.out.println(d);
        System.out.println(anotherAmount);

    }
}
